#include<iostream>
#include<string>

using namespace std;
//函数对象
//重载函数调用操作符的类，其对象成为函数对象
//函数对象使用重载的() 时，行为类似函数调用，也叫仿函数
//函数对象(仿函数) 的本质是一个类,并不是一个函数

/*
class MyAdd
{
public:
	int operator() (int v1, int v2)
	{
		return v1 + v2;
	}
};

//1.函数对象在使用时，可以像普通函数那样调用，可以有参数，可以有返回值  
void test01()
{
	MyAdd myadd;
	cout << myadd(10, 10) << endl;
}

//2.函数对象超出普通函数的概念，函数对象可以有自己的状态
class MyPrint
{
public:
	MyPrint()
	{
		this->count = 0;
	}

	void operator()(string test)
	{
		cout << test << endl;
		this->count++;
	}
	int count;
};
void test02()
{
	MyPrint print;
	print("hello world");
	print("hello world");
	print("hello world");
	print("hello world");
	cout << "print调用次数为: " << print.count << endl;
}
 
//3.函数对象可以作为参数传递
void doPrint(MyPrint& mp, string test)
{
	mp(test);
}

void test03()
{
	MyPrint print;
	doPrint(print, "hello C++");
}

int main()
{
	test01();
	test02();
	test03();
	return 0;
}
*/






/*
//谓词--返回bool类型的仿函数成为谓词
//如果operator()接受一个参数，称为一元谓词，两个参数即为二元谓词

#include<vector>
#include<algorithm>

//一元谓词
struct GreaterFive
{
	bool operator()(int val)
	{
		return val > 5;
	}
};
void test01()
{
	vector<int> v;
	for (int i = 0; i < 10; i++)
	{
		v.push_back(i);
	}

	//查找容器中有没有大于5的容器
	//GreateFive 匿名函数对象	
	vector<int>::iterator it = find_if(v.begin(), v.end(), GreaterFive());
	if (it == v.end())
	{
		cout << "未找到" << endl;
	}
	else
	{
		cout << "找到了大于5的数字为: " << *it << endl;
	}
	//返回该元素元素的迭代器
}

//二元谓词
class MyCompare
{
public:
	bool operator()(int v1, int v2)
	{
		return v1 > v2;
	}
};

void test02()
{
	vector<int> v;
	v.push_back(10);
	v.push_back(20);
	v.push_back(40);
	v.push_back(30);

	sort(v.begin(), v.end());
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;

	//使用函数对象，改变算法策略，更改排序规则从大到小
	sort(v.begin(), v.end(), MyCompare());
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}

int main()
{
	test01();
	test02();
	return 0;
}
*/






//内建函数对象
//STL内建了一些函数对象，有: 算术仿函数， 关系仿函数， 逻辑仿函数
//需要引头文件#include<functional>


//算数仿函数
/*
tmplate<class T> T plus<T>			//加法仿函数
tmplate<class T> T minus<T>			//减法仿函数
tmplate<class T> T multiplies<T>	//乘法仿函数
tmplate<class T> T divides<T>		//除法仿函数
tmplate<class T> T modulus<T>		//取模仿函数
tmplate<class T> T negate<T>		//取反仿函数

*/
/*
#include<functional>
void test01()
{
	negate<int> n;
	cout << n(50) << endl;

	plus<int> m;
	cout << m(59, 39) << endl;
}

int main()
{
	test01();
	return 0;
}
*/




//关系仿函数
/*
tmplate<class T> T equal_to<T>			//等于
tmplate<class T> T not_equal_to<T>		//不等于
tmplate<class T> T greater<T>			//大于
tmplate<class T> T greater_equal<T>		//大于等于
tmplate<class T> T less<T>				//小于
tmplate<class T> T less_qrual<T>		//小于等于

*/
/*
#include<vector>
#include<functional>
#include<algorithm>
class MyCompare
{
public:
	bool operator() (int v1, int v2)
	{
		return v1 > v2;
	}
};
void test01()
{
	vector<int> v;
	v.push_back(10);
	v.push_back(50);
	v.push_back(30);
	v.push_back(40);
	v.push_back(60);
	v.push_back(20);

	for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;

	//降序
	//sort(v.begin(), v.end(), MyCompare());
	sort(v.begin(), v.end(), greater<int>());

	for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}
int main()
{
	test01();
	return 0;
}
*/






//逻辑仿函数
//逻辑仿函数在实际运用中用的并不多。
/*
tmplate<class T> bool logical_and<T>	//逻辑与
tmplate<class T> bool logical_or<T>		//逻辑或
tmplate<class T> bool logical_not<T>	//逻辑非
*/

#include<functional>
#include<vector>
#include<algorithm>

void test01()
{
	vector<bool> v;
	v.push_back(true);
	v.push_back(false);
	v.push_back(true);
	v.push_back(false);

	for (vector<bool>::iterator it = v.begin(); it != v.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
	//利用逻辑非，将容器v搬运到容器v2中，并执行取反操作

	vector<bool> v2;
	//先要开辟空间
	v2.resize(v.size());

	transform(v.begin(), v.end(), v2.begin(), logical_not<bool>());
	for (vector<bool>::iterator it = v2.begin(); it != v2.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}

int main()
{
	test01();
	return 0;
}

















